package com.fayou.cloud.cloudgatewaygateway9527.filter;

import com.alibaba.fastjson.JSON;
import com.fayou.cloud.entites.ResponseCodeEnum;
import com.fayou.cloud.entites.ResponseResult;
import com.fayou.cloud.exception.TokenAuthenticationException;
import com.fayou.cloud.util.JWTUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.omg.CORBA.ServerRequest;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

import java.util.Date;
import java.util.List;

@Component
@Slf4j
public class AuthorizeFilter implements GlobalFilter, Ordered {
    @Value("${secretKey:123456}")
    private String secretKey;


    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        ServerHttpRequest request = exchange.getRequest();
        ServerHttpResponse response = exchange.getResponse();
        String uri = request.getURI().getPath();

        //  检查白名单（配置）
        if (uri.contains("/auth-server/login")) {
            return chain.filter(exchange);
        }


        String token = request.getHeaders().getFirst("token");
        if (StringUtils.isBlank(token)) {
            response.setStatusCode(HttpStatus.UNAUTHORIZED);
            return getVoidMono(response, ResponseCodeEnum.TOKEN_MISSION);
        }

        try {
            JWTUtil.verifyToken(token, secretKey);
        } catch (TokenAuthenticationException ex) {
            return getVoidMono(response, ResponseCodeEnum.TOKEN_INVALID);
        } catch (Exception ex) {
            return getVoidMono(response, ResponseCodeEnum.UNKNOWN_ERROR);
        }

        String userName = JWTUtil.getUserInfo(token);
        //注意这个方法，方法名是：改变，这个是修改ServerWebExchange属性的方法，
        // 返回的是一个Builder实例，Builder是ServerWebExchange的内部类
        ServerHttpRequest mutableReq = request.mutate().header("userName", userName).build();
        ServerWebExchange mutableExchange = exchange.mutate().request(mutableReq).build();

        return chain.filter(mutableExchange);

    }

    @Override
    public int getOrder() {
        return -100;
    }

    private Mono<Void> getVoidMono(ServerHttpResponse serverHttpResponse, ResponseCodeEnum responseCodeEnum) {
        serverHttpResponse.getHeaders().add("Content-Type", "application/json;charset=UTF-8");
        ResponseResult responseResult = ResponseResult.error(responseCodeEnum.getCode(), responseCodeEnum.getMessage());
        DataBuffer dataBuffer = serverHttpResponse.bufferFactory().wrap(JSON.toJSONString(responseResult).getBytes());
        return serverHttpResponse.writeWith(Flux.just(dataBuffer));
    }

}
